package com.library.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.library.Filter.CaptchaFilter;
import com.library.constant.MessageConstant;
import com.library.properties.JwtProperties;
import com.library.result.Result;
import com.library.utils.JwtUtil;
import com.library.vo.UserLoginVO;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import java.util.HashMap;
import java.util.Map;

import static org.springframework.security.config.Customizer.withDefaults;

@Configuration
@EnableWebSecurity
@Slf4j
public class WebSecurityConfig {

    @Autowired
    private JwtProperties jwtProperties;
    @Autowired
    private RedisTemplate redisTemplate;
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        //authorizeRequests()：开启授权保护
        //anyRequest()：对所有请求开启授权保护
        //authenticated()：已认证请求会自动被授权
        http
                .authorizeRequests(authorize ->
                        authorize
                                .antMatchers( "/api/user/register", "/api/common/captcha","/api/common/upload").permitAll()
                                .antMatchers("/api/admin/**").hasRole("ADMIN")
                                .antMatchers("/api/user/**").hasAnyRole("USER", "ADMIN")
                                .anyRequest()//对所有请求开启授权保护
                                .authenticated())//已认证的请求会被自动授权
                .addFilterBefore(new CaptchaFilter(redisTemplate), UsernamePasswordAuthenticationFilter.class)
                .formLogin(form -> {
                    form
                            .loginPage("/api/user/login").permitAll() //登录页面无需授权即可访问
                            .usernameParameter("username") //自定义表单用户名参数，默认是username
                            .passwordParameter("password") //自定义表单密码参数，默认是password
                            .loginProcessingUrl("/api/user/login")
                            //.failureUrl("/login?error") //登录失败的返回地址
                            .successHandler(authenticationSuccessHandler())
                            .failureHandler(authenticationFailureHandler())
                    ;
                })//表单授权方式
                .logout(logout -> {
                    logout
                            .logoutUrl("/api/user/logout")
                            .logoutSuccessHandler((request, response, authentication) -> {
                                Result<Object> result = Result.success();
                                ObjectMapper objectMapper = new ObjectMapper();
                                response.setContentType("application/json;charset=UTF-8");
                                response.getWriter().write(objectMapper.writeValueAsString(result));
                            });
                })
               //.formLogin(withDefaults())//表单授权方式
                .httpBasic(withDefaults());//基本授权方式

        //关闭csrf攻击防御
        http.csrf((csrf) -> {
            csrf.disable();
        });
        //跨域
        http.cors(withDefaults());

        return http.build();
    }

    private AuthenticationSuccessHandler authenticationSuccessHandler() {
        return (request, response, authentication) -> {
            CustomUserDetails customUserDetails = (CustomUserDetails) authentication.getPrincipal();
            Map<String, Object> claims = new HashMap<>();
            claims.put("userId", customUserDetails.getUserId());
            String token = JwtUtil.createJWT(
                    jwtProperties.getUserSecretKey(),
                    jwtProperties.getUserTtl(),
                    claims);
            UserLoginVO userLoginVO = UserLoginVO.builder()
                    .id(customUserDetails.getUserId())
                    .username(customUserDetails.getUsername())
                    .token(token)
                    .build();
            Result<UserLoginVO> result = Result.success(userLoginVO);
            response.setContentType("application/json;charset=UTF-8");
            ObjectMapper objectMapper = new ObjectMapper();
            response.getWriter().write(objectMapper.writeValueAsString(result));
        };
    }

    private AuthenticationFailureHandler authenticationFailureHandler() {
        return (request, response, exception) -> {
            Result<Object> result = Result.error(MessageConstant.PASSWORD_ERROR);
            ObjectMapper objectMapper = new ObjectMapper();
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(objectMapper.writeValueAsString(result));
        };
    }


    @Bean
    public UserDetailsService userDetailsService() {
        DBUserDetailsManager manager = new DBUserDetailsManager();
        return manager;
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        // 这里可以根据需要调整哈希次数
        return new CustomPasswordEncoder();
    }

}
